import { deepClone, Emitter } from '@/ts/base/common';
import { IProperty, IReport, orgAuth } from '@/ts/core';
import { Form } from 'devextreme-react';
import { GroupItem, SimpleItem } from 'devextreme-react/form';
import React, { useState, useEffect } from 'react';
import { ValueChangedEvent } from 'devextreme/ui/text_box';
import useObjectUpdate from '@/hooks/useObjectUpdate';
import { Button, message, Popconfirm } from 'antd';
import OpenFileDialog from '@/components/OpenFileDialog';
import cls from '../design/index.module.less';
import { XFloatRowsInfo, XRowsInfo } from '@/ts/base/schema';
import { loadwidgetOptions } from '../../WorkForm/Utils';
import { DeleteOutlined, EditOutlined } from '@ant-design/icons';
import { model } from '@/ts/base';
import ValidateRule from './reportRule/modal/validateRule';

interface IRowInfoProps {
  current: IReport;
  rowInfo: XFloatRowsInfo | undefined;
  notifyEmitter: Emitter;
}

const FloatRowsConfig: React.FC<IRowInfoProps> = ({
  current,
  rowInfo,
  notifyEmitter,
}) => {
  const [key, _forceUpdate] = useObjectUpdate(current);
  const [formData, setFormData] = useState(rowInfo as XFloatRowsInfo);
  const [center, setCenter] = useState(<></>);
  const [select, setSelect] = useState<model.Rule>();
  const [openType, setOpenType] = useState(0);
  const [row, setRow] = useState<XRowsInfo | undefined>(undefined);
  useEffect(() => {
    if (rowInfo) {
      const data = deepClone(rowInfo);
      data.rowsInfo.forEach((row) => {
        if (row.rule.ruleString) {
          row.rule.ruleString = JSON.stringify(JSON.parse(row.rule.ruleString));
        } else {
          row.rule.ruleString = JSON.stringify([]);
        }
        if (!row.categoryConfig) {
          row.categoryConfig = {};
        }
      });
      setFormData(data);
    }
  }, [rowInfo]);

  const notityAttrChanged = () => {
    setFormData({ ...formData });
  };

  const renderFormItems = () => {
    if (!formData?.rowsInfo) {
      return <></>;
    }

    const renderValidationRules = (rowInfo: XRowsInfo) => {
      let rules = JSON.parse(rowInfo.rule.ruleString ?? '[]');
      if (!Array.isArray(rules)) {
        rules = [rules];
      }
      return (
        <div>
          {rules.map((rule: model.Rule, index: number) => (
            <div key={index} style={{ marginBottom: '10px' }}>
              <span>规则 {rule.name}: </span>
              <Button
                type="link"
                icon={<EditOutlined />}
                onClick={() => {
                  setRow(rowInfo);
                  setSelect(rule);
                  setOpenType(1);
                }}>
                编辑
              </Button>
              <Popconfirm
                title="确定删除吗？"
                onConfirm={() => {
                  const updatedRules = rules.filter((_: any, i: number) => i !== index);
                  rowInfo.rule.ruleString = JSON.stringify(updatedRules);
                  notityAttrChanged();
                }}>
                <Button type="link" icon={<DeleteOutlined />} danger>
                  删除
                </Button>
              </Popconfirm>
            </div>
          ))}
          <Button
            type="link"
            onClick={() => {
              setRow(rowInfo);
              setOpenType(1);
              setSelect(undefined);
            }}>
            添加校验规则
          </Button>
        </div>
      );
    };

    return formData?.rowsInfo.map((rowInfo, index) => {
      return (
        <GroupItem key={index} cssClass={cls.formGroup}>
          <SimpleItem>
            <span>字段：{rowInfo?.name}</span>
          </SimpleItem>
          <SimpleItem
            dataField={`rowsInfo[${index}].rule.value.type`}
            editorType="dxSelectBox"
            label={{ text: '数据类型' }}
            editorOptions={{
              items: [
                { key: '输入型', text: '输入型' },
                { key: '属性型', text: '属性型' },
                { key: '函数型', text: '函数型' },
              ],
              displayExpr: 'text',
              valueExpr: 'text',
              value: rowInfo.rule.value?.type || '输入型',
            }}
          />
          {rowInfo?.rule.value?.type === '函数型' && (
            <SimpleItem
              editorType="dxTextArea"
              dataField={`rowsInfo[${index}].rule.value.valueString`}
              label={{ text: '数据值' }}
              editorOptions={{
                height: 120,
              }}
            />
          )}
          {rowInfo?.rule.value?.type === '属性型' && (
            <SimpleItem label={{ text: '引用其他属性' }}>
              <Button
                size="small"
                style={{ marginRight: '5px' }}
                onClick={() =>
                  setCenter(
                    <OpenFileDialog
                      title={`选择属性`}
                      accepts={['属性']}
                      rootKey={current.spaceKey}
                      excludeIds={[]}
                      onCancel={() => setCenter(<></>)}
                      onOk={(files) => {
                        (files as IProperty[]).forEach((item) => {
                          formData.rowsInfo[index].rule.value!.valueString = {
                            propId: item.id,
                            property: item.metadata,
                            ...item.metadata,
                            id: 'snowId()',
                            rule: '{}',
                            queryRule: '',
                            options: {
                              visible: true,
                              isRequired: false,
                            },
                            formId: current.id,
                            authId: orgAuth.SuperAuthId,
                          };
                        });
                        setCenter(<></>);
                      }}
                    />,
                  )
                }>
                配置
              </Button>
              {rowInfo.rule.value?.valueString?.name}
            </SimpleItem>
          )}
          {rowInfo?.rule.value?.type === '属性型' && (
            <SimpleItem
              dataField={`rowsInfo[${index}].rule.value.valueString.widget`}
              editorType="dxSelectBox"
              label={{ text: '组件' }}
              editorOptions={{
                items: loadwidgetOptions(rowInfo.rule.value.valueString ?? []),
              }}
            />
          )}
          <SimpleItem
            dataField={`rowsInfo[${index}].valueType`}
            editorType="dxSelectBox"
            label={{ text: '字段类型' }}
            editorOptions={{
              items: [
                { key: '文本框', text: '文本框' },
                { key: '数字框', text: '数字框' },
                { key: '日期型', text: '日期型' },
                { key: '分类型', text: '分类型' },
              ],
              displayExpr: 'text',
              valueExpr: 'text',
              value: rowInfo?.valueType || '文本框',
            }}
          />
          {rowInfo?.valueType === '分类型' && (
            <SimpleItem label={{ text: '分类型配置' }}>
              <Button
                size="small"
                style={{ marginRight: '5px' }}
                onClick={() =>
                  setCenter(
                    <OpenFileDialog
                      title={`选择分类型配置`}
                      accepts={['属性']}
                      rootKey={current.spaceKey}
                      excludeIds={[]}
                      onCancel={() => setCenter(<></>)}
                      onOk={(files) => {
                        const selectedItem = files[0] as IProperty;
                        setFormData(prevData => {
                          const updatedData = deepClone(prevData);
                          const currentRow = updatedData.rowsInfo[index];
                          currentRow.categoryConfig = {
                            propId: selectedItem.id,
                            property: selectedItem.metadata,
                            ...selectedItem.metadata,
                            id: 'snowId()',
                            rule: '{}',
                            queryRule: '',
                            options: {
                              visible: true,
                              isRequired: false,
                            },
                            formId: current.id,
                            authId: orgAuth.SuperAuthId,
                          };
                          currentRow.valueType = '分类型';
                          return updatedData;
                        });
                        setCenter(<></>);
                      }}
                    />,
                  )
                }>
                配置
              </Button>
              {rowInfo.categoryConfig?.name || ''}
            </SimpleItem>
          )}
          {rowInfo?.valueType === '数字框' && (
            <SimpleItem
              dataField={`rowsInfo[${index}].accuracy`}
              label={{ text: '精度' }}
            />
          )}
          <SimpleItem
            dataField={`rowsInfo[${index}].isLineNumber`}
            editorType="dxCheckBox"
            label={{ text: '是否序号' }}
          />
          {rowInfo?.isLineNumber === true && (
            <SimpleItem
              dataField={`rowsInfo[${index}].startLineNumber`}
              label={{ text: '序号起始值' }}
            />
          )}
          <SimpleItem
            dataField={`rowsInfo[${index}].isOnlyRead`}
            editorType="dxCheckBox"
            label={{ text: '是否只读' }}
          />
          {rowInfo?.rule.value?.type === '函数型' && (
            <SimpleItem
              dataField={`rowsInfo[${index}].rule.isVariableData`}
              editorType="dxCheckBox"
              label={{ text: '是否变量集取数' }}
            />
          )}
          <SimpleItem
            label={{ text: '校验规则', visible: true }}
            render={() => renderValidationRules(rowInfo)}
          />
        </GroupItem>
      );
    });
  };

  return (
    <>
      <Form
        key={key}
        height={'calc(100vh - 130px)'}
        scrollingEnabled
        formData={formData}
        onFieldDataChanged={notityAttrChanged}>
        <SimpleItem>
          <span>多选：{formData?.coords}</span>
        </SimpleItem>
        <SimpleItem isRequired dataField="floatRowCode" label={{ text: '代码' }} />
        <SimpleItem
          dataField="isFloatRows"
          editorType="dxCheckBox"
          label={{ text: '浮动行' }}
          editorOptions={{
            onValueChanged: (_e: ValueChangedEvent) => {
              notifyEmitter.changCallback('isFloatRows', formData);
            },
          }}
        />
        {formData?.isFloatRows && renderFormItems()}
        {formData?.isFloatRows && (
          <SimpleItem>
            <div
              style={{
                width: '100%',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
                padding: '20px 0',
              }}>
              <Button
                onClick={() => {
                  if (!formData.floatRowCode) {
                    message.error('请填写浮动行代码~');
                    return;
                  } else {
                    notifyEmitter.changCallback('row', formData);
                  }
                }}>
                批量生成
              </Button>
            </div>
          </SimpleItem>
        )}
      </Form>
      {openType == 1 && (
        <ValidateRule
          reports={[current.metadata]}
          onCancel={() => setOpenType(0)}
          current={select as model.NodeValidateRule}
          targetId={rowInfo?.attributeId!}
          onOk={(rule) => {
            const data = deepClone(formData);
            const rowInfo = data.rowsInfo.find((r) => r.name === row?.name);
            if (rowInfo) {
              let rules = JSON.parse(rowInfo.rule.ruleString ?? '[]');
              if (!Array.isArray(rules)) {
                rules = [rules];
              }
              if (select) {
                const index = rules.findIndex((r: model.Rule) => r.id === select.id);
                if (index !== -1) {
                  rules[index] = rule;
                }
              } else {
                rules.push(rule);
              }
              rowInfo.rule.ruleString = JSON.stringify(rules);
            }
            setFormData(data);
            setOpenType(0);
          }}
        />
      )}
      {center}
    </>
  );
};

export default FloatRowsConfig;
